package com.ruicar.afs.cloud.risk.api.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.dynamicrequest.DynamicRequest;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.service.ServiceInfo;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.risk.api.config.RiskControlServerConfig;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.TortoiseResultNotice;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.notice.*;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.TortoiseQueryBean;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.request.TortoiseFraudPushData;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.request.TortoiseApplyData;
import com.ruicar.afs.cloud.risk.api.dto.tortoise.request.TortoisePrevApproveData;
import com.ruicar.afs.cloud.risk.api.enums.RiskControlRequestPath;
import com.ruicar.afs.cloud.risk.api.enums.tortoise.GwtTortoiseScene;
import com.ruicar.afs.cloud.risk.api.service.AfsRiskControlService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

/**
 * @Description
 * @Author Peng Jinbo
 * @Date 2020/07/24 15:24
 */
@Service
@AllArgsConstructor
@Slf4j
public class AfsRiskControlServiceImpl implements AfsRiskControlService {
    /**
     * Dynamic request
     */
    private DynamicRequest dynamicRequest;
    /**
     * Risk server config
     */
    private RiskControlServerConfig riskServerConfig;

    /**
     * Author Peng Jinbo
     * Tortoise signal *
     *
     * @param queryBean business data
     */
    private String signal(TortoiseQueryBean queryBean, RiskControlRequestPath path) {
        log.info("风控玄武调用 applyNo:{},serialNumber:{},req=>{}", queryBean.getApplyNo(), queryBean.getSerialNumber(), queryBean.getApplyNo());
        queryBean.setServerName(ServiceInfo.getServiceName());
        IResponse<String> response = dynamicRequest.post(riskServerConfig.getRiskServer(), AfsEnumUtil.key(path), queryBean, new TypeReference<String>() {
        });
        Assert.isTrue(StrUtil.equals(CommonConstants.SUCCESS, response.getCode()), response.getMsg());
        Assert.isTrue(StrUtil.isNotBlank(response.getData()), "玄武返回唯一标识为空,操作失败");
        log.info("风控玄武响应 applyNo:{},serialNumber:{}, resp=>{}", queryBean.getApplyNo(), queryBean.getSerialNumber(), response);
        return response.getData();
    }

    @Override
    public String signalApply(TortoiseApplyData applyData) {
        applyData.setScene(GwtTortoiseScene.NORMAL_APPLY);
        return signal(applyData, RiskControlRequestPath.SIGNAL_APPLY);
    }

    @Override
    public String signalFraudHandInvoke(TortoiseApplyData applyData) {
        applyData.setScene(GwtTortoiseScene.HAND_ANTI_FRAUD_INVOKE);
        return signal(applyData, RiskControlRequestPath.SIGNAL_FRAUD_HAND);
    }

    @Override
    public String signalDecisionHandInvoke(TortoiseApplyData applyData) {
        applyData.setScene(GwtTortoiseScene.HAND_DECISION_INVOKE);
        return signal(applyData, RiskControlRequestPath.SIGNAL_DECISION_HAND);
    }

    @Override
    public String signalPrevApprove(TortoisePrevApproveData prevApproveData) {
        prevApproveData.setScene(GwtTortoiseScene.PREV_APPROVE);
        return signal(prevApproveData, RiskControlRequestPath.SIGNAL_PREV_APPROVE);
    }

    @Override
    public String signalFraudPush(TortoiseFraudPushData fraudPushData) {
        fraudPushData.setScene(GwtTortoiseScene.FRAUD_PUSH);
        return signal(fraudPushData, RiskControlRequestPath.SIGNAL_FRAUD_PUSH);
    }

    /**
     * Author Peng Jinbo
     * Query notice tortoise result notice
     *
     * @param queryBean query bean
     * @return the tortoise result notice
     */
    @Override
    public TortoiseResultNotice queryNotice(TortoiseQueryBean queryBean) {
        log.info("玄武结果获取 req=>{}", queryBean);
        IResponse<TortoiseResultNotice> response = dynamicRequest.post(riskServerConfig.getRiskServer(), AfsEnumUtil.key(RiskControlRequestPath.NOTICE_QUERY), queryBean, new TypeReference<TortoiseResultNotice>() {
        });
        Class noticeDataClz;
        switch (queryBean.getScene()) {
            case NORMAL_APPLY:
                noticeDataClz = TortoiseApplyNoticeInfo.class;
                break;
            case PREV_APPROVE:
                noticeDataClz = TortoisePrevApproveNoticeInfo.class;
                break;
            case FRAUD_PUSH:
                noticeDataClz = TortoiseFraudPushNoticeInfo.class;
                break;
            case HAND_ANTI_FRAUD_INVOKE:
                noticeDataClz = TortoiseHandFraudNoticeInfo.class;
                break;
            case HAND_DECISION_INVOKE:
                noticeDataClz = TortoiseHandDecisionNoticeInfo.class;
                break;
            default:
                throw new AfsBaseException("未明确场景，处理失败");
        }
        response.getData().setNoticeInfo(((JSONObject) response.getData().getNoticeInfo()).toJavaObject(noticeDataClz));
        log.info("玄武结果获取 resp=>{}", response);
        return response.getData();
    }

    @Override
    public TortoiseResultNotice<TortoiseApplyNoticeInfo> queryApplyNotice(TortoiseQueryBean queryBean) {
        queryBean.setScene(GwtTortoiseScene.NORMAL_APPLY);
        return queryNotice(queryBean);
    }

    @Override
    public TortoiseResultNotice<TortoiseHandFraudNoticeInfo> queryFraudHandInvokeNotice(TortoiseQueryBean queryBean) {
        queryBean.setScene(GwtTortoiseScene.HAND_ANTI_FRAUD_INVOKE);
        return queryNotice(queryBean);
    }

    @Override
    public TortoiseResultNotice<TortoiseHandDecisionNoticeInfo> queryDecisionHandInvokeNotice(TortoiseQueryBean queryBean) {
        queryBean.setScene(GwtTortoiseScene.HAND_DECISION_INVOKE);
        return queryNotice(queryBean);
    }

    @Override
    public TortoiseResultNotice<TortoisePrevApproveNoticeInfo> queryPrevApproveNotice(TortoiseQueryBean queryBean) {
        queryBean.setScene(GwtTortoiseScene.PREV_APPROVE);
        return queryNotice(queryBean);
    }

    @Override
    public TortoiseResultNotice<TortoiseFraudPushNoticeInfo> queryFraudPushNotice(TortoiseQueryBean queryBean) {
        queryBean.setScene(GwtTortoiseScene.FRAUD_PUSH);
        return queryNotice(queryBean);
    }
}
